from fastapi import Request, status
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException as StarletteHTTPException

from app.schemas.response import Response, ResponseCode


async def validation_exception_handler(request: Request, exc: RequestValidationError):
    """请求验证异常处理器
    
    处理请求体验证失败的情况
    
    Args:
        request: 请求对象
        exc: 验证异常
        
    Returns:
        JSONResponse: JSON格式的错误响应
    """
    # 获取验证错误的详细信息
    error_detail = exc.errors()
    error_msg = "请求数据验证失败"
    
    # 尝试提取更具体的错误信息
    if error_detail and len(error_detail) > 0:
        first_error = error_detail[0]
        if "msg" in first_error:
            error_msg = f"{error_msg}: {first_error['msg']}"
        if "loc" in first_error and len(first_error["loc"]) > 1:
            error_msg = f"{error_msg}, 错误字段: {'.'.join([str(loc) for loc in first_error['loc'][1:]])}"
    
    return JSONResponse(
        status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
        content=Response.fail(
            code=ResponseCode.BAD_REQUEST,
            message=error_msg
        ).dict()
    )


async def http_exception_handler(request: Request, exc: StarletteHTTPException):
    """HTTP异常处理器
    
    处理HTTP异常
    
    Args:
        request: 请求对象
        exc: HTTP异常
        
    Returns:
        JSONResponse: JSON格式的错误响应
    """
    # 根据状态码映射到自定义状态码
    code = ResponseCode.BAD_REQUEST
    if exc.status_code == status.HTTP_401_UNAUTHORIZED:
        code = ResponseCode.UNAUTHORIZED
    elif exc.status_code == status.HTTP_403_FORBIDDEN:
        code = ResponseCode.FORBIDDEN
    elif exc.status_code == status.HTTP_404_NOT_FOUND:
        code = ResponseCode.NOT_FOUND
    elif exc.status_code >= 500:
        code = ResponseCode.INTERNAL_ERROR
    
    return JSONResponse(
        status_code=exc.status_code,
        content=Response.fail(
            code=code,
            message=str(exc.detail)
        ).dict()
    )


async def general_exception_handler(request: Request, exc: Exception):
    """通用异常处理器
    
    处理所有未捕获的异常
    
    Args:
        request: 请求对象
        exc: 异常
        
    Returns:
        JSONResponse: JSON格式的错误响应
    """
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content=Response.error(message=f"服务器内部错误: {str(exc)}").dict()
    ) 